package com.stony.orc;

import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;

/**
 * <p>orcTest
 * <p>com.stony.orc
 *
 * @author stony
 * @version 下午6:10
 * @since 2017/11/15
 */
public class ImageUtils {
    private static final Logger logger = LoggerFactory.getLogger(ImageUtils.class);
    /**
     * 根据指定大小和指定精度压缩图片
     *
     * @param srcPath     源图片地址
     * @param desPath     目标图片地址
     * @param desFileSize 指定图片大小，单位kb
     * @param accuracy    精度，递归压缩的比率，建议小于0.9
     * @return
     */
    public static String compressPicForScale(String srcPath, String desPath, long desFileSize, double accuracy) {
        if (isEmpty(srcPath) || isEmpty(srcPath)) {
            return null;
        }
        if (!new File(srcPath).exists()) {
            return null;
        }
        try {
            File srcFile = new File(srcPath);
            long srcFileSize = srcFile.length();
            logger.info("开始压缩源图片：" + srcPath + "，大小：" + srcFileSize / 1024 + "kb");

            // 1、先转换成jpg
            Thumbnails.of(srcPath).scale(1f).toFile(desPath);
            // 递归压缩，直到目标文件大小小于desFileSize
            commpressPicCycle(desPath, desFileSize, accuracy);

            File desFile = new File(desPath);
            logger.info("完成压缩目标图片：" + desPath + "，大小" + desFile.length() / 1024 + "kb");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return desPath;
    }


    private static void commpressPicCycle(String desPath, long desFileSize, double accuracy) throws IOException {
        File srcFileJPG = new File(desPath);
        long srcFileSizeJPG = srcFileJPG.length();
        // 2、判断大小，如果小于 desFileSize kb，不压缩；如果大于等于 desFileSize kb，压缩
        if (srcFileSizeJPG <= desFileSize * 1024) {
            return;
        }
        // 计算宽高
        BufferedImage bim = ImageIO.read(srcFileJPG);
        int srcWidth = bim.getWidth();
        int srcHeight = bim.getHeight();
        int desWidth = new BigDecimal(srcWidth).multiply(new BigDecimal(accuracy)).intValue();
        int desHeight = new BigDecimal(srcHeight).multiply(new BigDecimal(accuracy)).intValue();

        Thumbnails.of(desPath).size(desWidth, desHeight).outputQuality(accuracy).toFile(desPath);
        commpressPicCycle(desPath, desFileSize, accuracy);
    }

    public static boolean isEmpty(String path) {
        return path == null || path.length() == 0;
    }

    public static boolean isNotEmpty(String word) {
        return !isEmpty(word);
    }

    /**
     * 将本地图片进行Base64位编码
     * 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
     *
     * @param imagePath 图片路径
     * @return 返回Base64编码过的字节数组字符串
     */
    public static String encodeImgageToBase64(String imagePath) {
        return encodeImgageToBase64(new File(imagePath));
    }

    /**
     * 将本地图片进行Base64位编码
     * 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
     *
     * @param imageFile 图片
     * @return 返回Base64编码过的字节数组字符串
     */
    public static String encodeImgageToBase64(File imageFile) {
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(encodeImage(imageFile));
    }

    /**
     * 将图片文件转化为字节数组字符串
     *
     * @param imageFile
     * @return
     */
    public static byte[] encodeImage(File imageFile) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(imageFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }
}
